PGMS_250135_아날로그 시계

초침이 다른 바늘과 겹치는지 확인하는 구현 문제

몇 가지 디테일을 넣어줘야 한다

  1. 12시 정각에는 모든 바늘이 겹치는데, 이때는 1회로 카운트 한다
  2. 시작할 때 겹쳐서 시작한다면 그것도 카운트 한다

반복문으로 시작 시간 ~ 끝나는 시간을 초로 변환해서 1초마다 검사했다
시작 시간에 다른 바늘과 겹쳐 있는지는 반복문 밖에서 체크하고 진입했다

처음에는 now = 시작 각도 + 1초마다 움직이는 각도로 줬었는데, 그렇게 하면 오차가 생겨서 i를 바로 각도로 변환하는 걸로 바꿨다

조건은 2개인데, 1) 분침이 겹치는 경우와 2) 시침이 겹치는 경우를 카운트 하지만 만일 분침이랑 시침 위치가 같다면 하나로만 카운트 하게 짰다

계산할 때 각도는 0 초과 ~ 360도 이하로 주고, 다음으로 넘어갈 때는 360 -> 0으로 바꿔줬다

package PGMS;

public class PGMS_250135_아날로그시계 {
    public int solution(int h1, int m1, int s1, int h2, int m2, int s2) {
        double angS = 360 / 60; // 1초에 초침이 움직이는 각도
        double angM = 6.0 / 60; // 1초에 분침이 움직이는 각도
        double angH = 0.5 / 60; // 1초에 시침이 움직이는 각도

        int startTime = s1 + m1 * 60 + h1 * 60 * 60;
        int endTime = s2 + m2 * 60 + h2 * 60 * 60;

        double h = (startTime * angH) % 360;
        double m = (startTime * angM) % 360;
        double s = (startTime * angS) % 360;

        int cnt = 0;

        if (h == s || m == s) {
            cnt++;
        }

        for (int i = startTime + 1; i <= endTime; i++) {
            double nowH = (i * angH) % 360 == 0 ? 360 : (i * angH) % 360;
            double nowM = (i * angM) % 360 == 0 ? 360 : (i * angM) % 360;
            double nowS = (i * angS) % 360 == 0 ? 360 : (i * angS) % 360;

            if (s < h && nowH <= nowS) {
                cnt++;
            }

            if (s < m && nowM <= nowS && nowM != nowH) {
                cnt++;
            }

            h = nowH % 360;
            m = nowM % 360;
            s = nowS % 360;
        }


        return cnt;
    }
}